home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / mig / dist / mig.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-29  |  8.1 KB  |  330 lines

  1. /* 
  2.  * Mach Operating System
  3.  * Copyright (c) 1991,1990 Carnegie Mellon University
  4.  * All Rights Reserved.
  5.  * 
  6.  * Permission to use, copy, modify and distribute this software and its
  7.  * documentation is hereby granted, provided that both the copyright
  8.  * notice and this permission notice appear in all copies of the
  9.  * software, derivative works or modified versions, and any portions
  10.  * thereof, and that both notices appear in supporting documentation.
  11.  * 
  12.  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 
  13.  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
  14.  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  15.  * 
  16.  * Carnegie Mellon requests users of this software to return to
  17.  * 
  18.  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
  19.  *  School of Computer Science
  20.  *  Carnegie Mellon University
  21.  *  Pittsburgh PA 15213-3890
  22.  * 
  23.  * any improvements or extensions that they make and grant Carnegie the
  24.  * rights to redistribute these changes.
  25.  */
  26. /*
  27.  * HISTORY
  28.  * $Log:    mig.c,v $
  29.  * Revision 2.6  91/08/28  11:17:04  jsb
  30.  *     Removed TrapRoutine support.
  31.  *     [91/08/12            rpd]
  32.  * 
  33.  * Revision 2.5  91/06/25  10:31:32  rpd
  34.  *     Added ServerHeaderFileName and -sheader.
  35.  *     [91/05/22            rpd]
  36.  * 
  37.  * Revision 2.4  91/02/05  17:55:02  mrt
  38.  *     Changed to new Mach copyright
  39.  *     [91/02/01  17:54:42  mrt]
  40.  * 
  41.  * Revision 2.3  90/06/19  23:01:01  rpd
  42.  *     Added prefix argument to -i option.
  43.  *     Replaced GenIndividualUser with UserFilePrefix.
  44.  *     [90/06/03            rpd]
  45.  * 
  46.  * Revision 2.2  90/06/02  15:04:59  rpd
  47.  *     Created for new IPC.
  48.  *     [90/03/26  21:11:47  rpd]
  49.  * 
  50.  * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
  51.  *    Extensive revamping.  Added polymorphic arguments.
  52.  *    Allow multiple variable-sized inline arguments in messages.
  53.  *
  54.  *  8-Feb-89  David Golub (dbg) at Carnegie-Mellon University
  55.  *    Added -user, -server, and -header switches to name output files.
  56.  *    Added -i switch to write individual files for user routines.
  57.  *
  58.  * 17-Aug-87  Bennet Yee (bsy) at Carnegie-Mellon University
  59.  *    Added -s,-S switches for generating a SymTab
  60.  *
  61.  *  3-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
  62.  *    Removed -t,-T switch as code is now the same for
  63.  *    multi and single threaded use.
  64.  *
  65.  * 28-May-87  Richard Draves (rpd) at Carnegie-Mellon University
  66.  *    Created.
  67.  */
  68.  
  69. /*
  70.  *    Switches are;
  71.  *        -[v,Q]  verbose or not quiet:  prints out type
  72.  *            and routine information as mig runs.
  73.  *        -[V,q]  not verbose or quiet : don't print 
  74.  *            information during compilation
  75.  *            (this is the default)
  76.  *        -[r,R]  do or don't use rpc calls instead of 
  77.  *            send/receive pairs. Default is -r.
  78.  *        -[s,S]    generate symbol table or not:  generate a
  79.  *            table of rpc-name, number, routine triplets
  80.  *            as an external data structure -- main use is
  81.  *            for protection system's specification of rights
  82.  *            and for protection dispatch code.  Default is -s.
  83.  *        -i <prefix>
  84.  *            Put each user routine in its own file.  The
  85.  *            file is named <prefix><routine-name>.c.
  86.  *        -user <name>
  87.  *            Name the user-side file <name>
  88.  *        -server <name>
  89.  *            Name the server-side file <name>
  90.  *        -header <name>
  91.  *            Name the user-side header file <name>
  92.  *        -iheader <name>
  93.  *            Name the user-side internal header file <name>
  94.  *        -sheader <name>
  95.  *            NAme the server-side header file <name>
  96.  *
  97.  *  DESIGN:
  98.  *    Mig uses a lexxer module created by lex from lexxer.l and
  99.  *    a parser module created by yacc from parser.y to parse an
  100.  *    interface definitions module for a mach server.
  101.  *    The parser module calls routines in statement.c
  102.  *    and routines.c to build a list of statement structures.
  103.  *    The most interesting statements are the routine definitions
  104.  *    which contain information about the name, type, characteristics
  105.  *    of the routine, an argument list containing information for
  106.  *    each argument type, and a list of special arguments. The
  107.  *    argument type structures are build by routines in type.c
  108.  *    Once parsing is completed, the three code generation modules:
  109.  *    header.c user.c and server.c are called sequentially. These
  110.  *    do some code generation directly and also call the routines
  111.  *    in utils.c for common (parameterized) code generation.
  112.  *    
  113.  */
  114.  
  115. #include <stdio.h>
  116. #include "error.h"
  117. #include "lexxer.h"
  118. #include "global.h"
  119. #include "write.h"
  120.  
  121. extern int yyparse();
  122. static FILE *myfopen();
  123.  
  124. static void
  125. parseArgs(argc, argv)
  126.     int argc;
  127.     char *argv[];
  128. {
  129.     while (--argc > 0)
  130.     if ((++argv)[0][0] == '-') 
  131.     {
  132.         switch (argv[0][1]) 
  133.         {
  134.           case 'q':
  135.         BeQuiet = TRUE;
  136.         break;
  137.           case 'Q':
  138.         BeQuiet = FALSE;
  139.         break;
  140.           case 'v':
  141.         BeVerbose = TRUE;
  142.         break;
  143.           case 'V':
  144.         BeVerbose = FALSE;
  145.         break;
  146.           case 'r':
  147.         UseMsgRPC = TRUE;
  148.         break;
  149.           case 'R':
  150.         UseMsgRPC = FALSE;
  151.         break;
  152.           case 's':
  153.         if (streql(argv[0], "-server"))
  154.         {
  155.             --argc; ++argv;
  156.             if (argc == 0)
  157.             fatal("missing name for -server option");
  158.             ServerFileName = strmake(argv[0]);
  159.         }
  160.         else if (streql(argv[0], "-sheader"))
  161.         {
  162.             --argc; ++argv;
  163.             if (argc == 0)
  164.               fatal ("missing name for -sheader option");
  165.             ServerHeaderFileName = strmake(argv[0]);
  166.         }
  167.         else
  168.             GenSymTab = TRUE;
  169.         break;
  170.           case 'S':
  171.             GenSymTab = FALSE;
  172.         break;
  173.           case 'i':
  174.         if (streql(argv[0], "-iheader"))
  175.         {
  176.             --argc; ++argv;
  177.             if (argc == 0)
  178.             fatal("missing name for -iheader option");
  179.             InternalHeaderFileName = strmake(argv[0]);
  180.         }
  181.         else
  182.         {
  183.             --argc; ++argv;
  184.             if (argc == 0)
  185.             fatal("missing prefix for -i option");
  186.             UserFilePrefix = strmake(argv[0]);
  187.         }
  188.         break;
  189.           case 'u':
  190.         if (streql(argv[0], "-user"))
  191.         {
  192.             --argc; ++argv;
  193.             if (argc == 0)
  194.             fatal("missing name for -user option");
  195.             UserFileName = strmake(argv[0]);
  196.         }
  197.         else
  198.             fatal("unknown flag: '%s'", argv[0]);
  199.         break;
  200.           case 'h':
  201.         if (streql(argv[0], "-header"))
  202.         {
  203.             --argc; ++argv;
  204.             if (argc == 0)
  205.             fatal("missing name for -header option");
  206.             UserHeaderFileName = strmake(argv[0]);
  207.         }
  208.         else
  209.             fatal("unknown flag: '%s'", argv[0]);
  210.         break;
  211.           default:
  212.         fatal("unknown flag: '%s'", argv[0]);
  213.         /*NOTREACHED*/
  214.         }
  215.     }
  216.     else
  217.         fatal("bad argument: '%s'", *argv);
  218. }
  219.  
  220. void
  221. main(argc, argv)
  222.     int argc;
  223.     char *argv[];
  224. {
  225.     FILE *uheader, *server, *user;
  226.     FILE *iheader, *sheader;
  227.  
  228.     set_program_name("mig");
  229.     parseArgs(argc, argv);
  230.     init_global();
  231.     init_type();
  232.  
  233.     LookNormal();
  234.     (void) yyparse();
  235.  
  236.     if (errors > 0)
  237.     exit(1);
  238.  
  239.     more_global();
  240.  
  241.     uheader = myfopen(UserHeaderFileName, "w");
  242.     if (!UserFilePrefix)
  243.     user = myfopen(UserFileName, "w");
  244.     server = myfopen(ServerFileName, "w");
  245.     if (ServerHeaderFileName)
  246.     sheader = myfopen(ServerHeaderFileName, "w");
  247.     if (IsKernelServer)
  248.     {
  249.     iheader = myfopen(InternalHeaderFileName, "w");
  250.     }
  251.  
  252.     if (BeVerbose)
  253.     {
  254.     printf("Writing %s ... ", UserHeaderFileName);
  255.     fflush(stdout);
  256.     }
  257.     WriteUserHeader(uheader, stats);
  258.     fclose(uheader);
  259.     if (ServerHeaderFileName)
  260.     {
  261.     if (BeVerbose)
  262.     {
  263.         printf ("done.\nWriting %s ...", ServerHeaderFileName);
  264.         fflush (stdout);
  265.     }
  266.     WriteServerHeader(sheader, stats);
  267.     fclose(sheader);
  268.     }
  269.     if (IsKernelServer)
  270.     {
  271.     if (BeVerbose)
  272.     {
  273.         printf("done.\nWriting %s ... ", InternalHeaderFileName);
  274.         fflush(stdout);
  275.     }
  276.     WriteInternalHeader(iheader, stats);
  277.     fclose(iheader);
  278.     }
  279.     if (UserFilePrefix)
  280.     {
  281.     if (BeVerbose)
  282.     {
  283.         printf("done.\nWriting individual user files ... ");
  284.         fflush(stdout);
  285.     }
  286.     WriteUserIndividual(stats);
  287.     }
  288.     else
  289.     {
  290.     if (BeVerbose)
  291.     {
  292.         printf("done.\nWriting %s ... ", UserFileName);
  293.         fflush(stdout);
  294.     }
  295.     WriteUser(user, stats);
  296.     fclose(user);
  297.     }
  298.     if (BeVerbose)
  299.     {
  300.     printf("done.\nWriting %s ... ", ServerFileName);
  301.     fflush(stdout);
  302.     }
  303.     WriteServer(server, stats);
  304.     fclose(server);
  305.     if (BeVerbose)
  306.     printf("done.\n");
  307.  
  308.     exit(0);
  309. }
  310.  
  311. static FILE *
  312. myfopen(name, mode)
  313.     char *name;
  314.     char *mode;
  315. {
  316.     char *realname;
  317.     FILE *file;
  318.  
  319.     if (name == strNULL)
  320.     realname = "/dev/null";
  321.     else
  322.     realname = name;
  323.  
  324.     file = fopen(realname, mode);
  325.     if (file == NULL)
  326.     fatal("fopen(%s): %s", realname, unix_error_string(errno));
  327.  
  328.     return file;
  329. }
  330.